<?php

namespace app\service;

use app\core\Constant;
use app\core\exception\BusinessException;
use app\core\Request;
use app\core\Service;
use app\core\util\Encryp;
use app\core\util\Token;
use app\model\Goods;
use app\model\Member;
use app\model\MemberInfo;
use app\model\Order;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Cache;

/**
 * @extends Service<MemberService>
 */
class MemberService extends Service
{
    /**
     * 用户登录
     * @param string $mobile 帐号
     * @param string $password 密码
     * @param string $code code
     * @param string|null $company_name 企业名称
     * @return string
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function login(string $mobile, string $password)
    {
        $Member = Member::where([
            'mobile' => $mobile
        ])->find();
        if (!$Member) {
            throw new BusinessException('帐号不存在');
        }
        if ($Member['password'] !== Encryp::password($password)) {
            throw new BusinessException('密码不正确');
        }
        if ($Member['status'] != Constant::STATUS_NORMAL) {
            throw new BusinessException('帐号已禁用');
        }

        // 保存最后登录时间
        $Member->save([
            'login_time' => date('Y-m-d H:i:s', time()),
            'login_ip' => Request::invoke()->ip()
        ]);
        $memberInfo = $Member->toArray();
        // 生成 Token
        $token = Token::invoke()
            ->setMemberId($memberInfo['member_id'])
            ->setMemberInfo($memberInfo)
            ->genMemberToken();
        return $token;
    }

    public function httpGet($url, $header = array())
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        if (!empty($header)) {
            curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
        }

        curl_setopt($curl, CURLOPT_URL, $url);
        $res = curl_exec($curl);
        curl_close($curl);

        return $res;
    }

    public function save($data)
    {
        $data['invite_code'] = 'D6Q1VS';
        $inviteMemberInfo = Member::where('invite_code', $data['invite_code'])->find();
        if (!$inviteMemberInfo) {
            throw new BusinessException('邀请人不存在');
        }
        $Member = Member::where([
            'mobile' => $data['mobile']
        ])->find();
        if ($Member) {
            throw new BusinessException('帐号已存在');
        }
        Member::create([
            'pid' => $inviteMemberInfo['member_id'],
            'avatar' => 'http://pray.veac.cn/storage/avatar.png',
            'invite_pid' => $inviteMemberInfo['pid'] . '-' . $inviteMemberInfo['member_id'],
            'password' => Encryp::password($data['password']),
            'mobile' => $data['mobile'],
            'nick' => getName(),
            'status' => Constant::STATUS_NORMAL,
            'invite_code' => $this->getInvite()
        ]);
        return true;
    }


    public function getInvite()
    {
        $invite_code = generateRandomString();
        $inviteInfo = Member::where('invite_code', $invite_code)->find();
        if ($inviteInfo) {
            self::getInvite();
        }
        return $invite_code;
    }

    public function savePassword($password, $member_id)
    {
        $info = Member::where('member_id', $member_id)->find();
        if (empty($info)) {
            throw new \Exception('用户不存在');
        }
        $info->save([
            'password' => Encryp::password($password),
        ]);
        return true;
    }

    public function saveMember($data)
    {
        $info = Member::where('openid', $data['openid'])->find();
        if (empty($info)) {
            $info = [
                'avatar' => 'http://pray.veac.cn/storage/avatar.png',
                'openid' => $data['openid'],
                'nick' => getName(),
                'status' => Constant::STATUS_NORMAL,
                'invite_code' => $this->getInvite(),
                'session_key' => $data['session_key'],
                'login_time' => date('Y-m-d H:i:s', time()),
                'login_ip' => Request::invoke()->ip()
            ];
            $member = Member::create($info);
            if (!$member->member_id) {
                throw new \Exception('用户创建失败');
            }
            $memberInfo = $member->toArray();
        } else {
            $info->save([
                'session_key' => $data['session_key'],
                'login_time' => date('Y-m-d H:i:s', time()),
                'login_ip' => Request::invoke()->ip()
            ]);
            $memberInfo = $info->toArray();
        }
        // 生成 Token
        $token = Token::invoke()
            ->setMemberId($memberInfo['member_id'])
            ->setMemberInfo($memberInfo)
            ->genMemberToken();
        return $token;
    }

    public function saveJsOpenid($data)
    {
        $data['invite_code'] = 'D6Q1VS';
        $inviteMemberInfo = Member::where('invite_code', $data['invite_code'])->find();
        if (!$inviteMemberInfo) {
            throw new BusinessException('邀请人不存在');
        }
        $info = Member::where('js_openid', $data['js_openid'])->find();
        if (empty($info)) {
            $info = [
                'pid' => $inviteMemberInfo['member_id'],
                'avatar' => $data['avatar'] ?: 'http://pray.veac.cn/storage/avatar.png',
                'js_openid' => $data['js_openid'],
                'access_token' => $data['access_token'],
                'invite_code' => $this->getInvite(),
                'nick' => getName(),
                'status' => Constant::STATUS_NORMAL,
                'login_time' => date('Y-m-d H:i:s', time()),
                'login_ip' => Request::invoke()->ip()
            ];
            $member = Member::create($info);
            if (!$member->member_id) {
                throw new \Exception('用户创建失败');
            }
            $memberInfo = $member->toArray();
        } else {
            $info->save([
                'access_token' => $data['access_token'],
                'login_time' => date('Y-m-d H:i:s', time()),
                'login_ip' => Request::invoke()->ip()
            ]);
            $memberInfo = $info->toArray();
        }
        // 生成 Token
        $token = Token::invoke()
            ->setMemberId($memberInfo['member_id'])
            ->setMemberInfo($memberInfo)
            ->genMemberToken();
        return $token;
    }

    public function del($member_id)
    {
        $info = Member::find($member_id);
        if (!$info) {
            throw new BusinessException('用户不存在');
        }
        $info->delete();
    }

    public function delToken($member_id)
    {
        $info = Member::find($member_id);
        if (!$info) {
            throw new BusinessException('用户不存在');
        }
        $rs = Token::invoke()->delMemberToken($member_id);
        if (!$rs) {
            throw new BusinessException('token 不存在或失效');
        }
        return $rs;
    }

    public function saveMemberInfo($data, $member_id)
    {
        $MemberInfo = MemberInfo::where([
            'id_card' => $data['id_card']
        ])->find();
        if ($MemberInfo) {
            throw new BusinessException('实名认证信息已存在');
        }
        $identifyNum = urlencode($data['id_card']);
        $userName = urlencode($data['real_name']);
        $mobile = urlencode($data['mobile']);
        $host = "https://mobilecert.market.alicloudapi.com";
        $path = "/mobile3Meta";
        $method = "GET";
        $appcode = "d7ca6c75e0094a5a898a180ba039101d";
        $headers = array();
        array_push($headers, "Authorization:APPCODE " . $appcode);
        $querys = "identifyNum=$identifyNum&userName=$userName&mobile=$mobile";
        $url = $host . $path . "?" . $querys;
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_FAILONERROR, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HEADER, false);
        if (1 == strpos("$" . $host, "https://")) {
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        }
        $res = curl_exec($curl);
        $res = json_decode($res, true);
        if (!(!empty($res['data']) && $res['data']['bizCode'] == 1)) {
            throw new BusinessException('实名认证信息失败');
        }
        MemberInfo::create([
            'member_id' => $member_id,
            'real_name' => $data['real_name'],
            'id_card' => $data['id_card'],
            'bank_card' => $data['bank_card'],
            'bank_open' => $data['bank_open'],
            'bank_branch' => $data['bank_branch'],
            'mobile' => $data['mobile'],
            'id_card1' => $data['id_card1'],
            'id_card2' => $data['id_card2'],
        ]);
        return true;
    }

    public function findMemberInfo($member_id)
    {
        $MemberInfo = MemberInfo::where([
            'member_id' => $member_id
        ])->find();
        if (!$MemberInfo) {
            throw new BusinessException('实名认证信息不存在');
        }
        return $MemberInfo;
    }

    public function getMemberByMobile($mobile)
    {
        $info = Member::where([
            'mobile' => $mobile
        ])->find();
        if (!$info) {
            throw new BusinessException('用户不存在');
        }
        return $info;
    }

    public function getTeamList($page, $limit, $searchQuery = null)
    {
        $w = [];
        if (!empty($searchQuery['member_id']) && $searchQuery['member_id'] != '') {
            $w[] = ['pid', '=', $searchQuery['member_id']];
        }
        $parentMember = Member::where(['member_id' => $searchQuery['member_id']])->find()->toArray();
        $member = Member::where($w)->page($page, $limit)->field('member_id,pid,mobile,nick,avatar,create_time,level');
        $list = $member->select();
        foreach ($list as &$value) {
            if (!empty($parentMember['nick'])) {
                $value['pid_nick'] = $parentMember['nick'];
            } else {
                $value['pid_nick'] = '';
            }
        }
        return [
            'total' => $member->count(),
            'list' => $list,
        ];
    }

    public function getMemberNum($member_id)
    {
        $num = Member::where(['pid' => $member_id])->count();
        return $num;
    }

    public function getSubMemberAmount($member_id)
    {
        $list1 = Member::where(['pid' => $member_id])->select()->toArray();
        $list2 = $w = $where = [];
        if ($list1) {
            $member_ids = array_column($list1, 'member_id');
            $w[] = ['pid', 'in', $member_ids];
            $w[] = ['invite_pid', 'like', "%" . '-' . $member_id . '-' . "%"];
            $list2 = Member::where($w)->select()->toArray();
            $list = array_merge($list1, $list2);
            $sub_member_ids = array_column($list, 'member_id');
            $where[] = ['member_id', 'in', $sub_member_ids];
            $where[] = ['status', '=', 2];
            $daily_income = 0;
            $orderList = (new Order())->where($where)->select()->toArray();
            if ($orderList) {
                $goods_ids = array_column($orderList, 'goods_id');
                $goodsList = (new Goods())->where('goods_id', 'in', $goods_ids)->field('goods_id,daily_income')
                    ->select()->toArray();
                $goodsList = array_column($goodsList, null, 'goods_id');
                foreach ($orderList as $value) {
                    $daily_income = $daily_income + $goodsList[$value['goods_id']]['daily_income'];
                }
            }
            return $daily_income ?: 0;
        } else {
            return null;
        }
    }

    public function list($page, $limit, $searchQuery = null)
    {
        $w = [];
        if (!empty($searchQuery['type']) && $searchQuery['type'] != '') {
            $w[] = ['type', '=', $searchQuery['type']];
        }
        if (!empty($searchQuery['is_agent']) && $searchQuery['is_agent'] != '') {
            $w[] = ['is_agent', '=', $searchQuery['is_agent']];
        }
        if (!empty($searchQuery['mobile']) && $searchQuery['mobile'] != '') {
            $w[] = ['mobile', '=', $searchQuery['mobile']];
        }
        $map = Member::where($w)->page($page, $limit);
        return [
            'total' => $map->count(),
            'list' => $map->select()->toArray(),
        ];
    }

    public function info($id)
    {
        $info = Member::where('member_id', $id)->find();
        if (!$info) {
            throw new BusinessException('数据不存在');
        }

        return $info->toArray();
    }

    public function getRankingList($member_id)
    {
        $list = Member::where('pid', $member_id)->order('dis_commission desc')->field('member_id,avatar,mobile,nick,dis_commission')->select();
        return $list->toArray();
    }

    //缓存手机验证码
    public function saveCode($code, $mobile)
    {
        $cacheData = [
            'time' => time(),
            'code' => $code
        ];
        Cache::set('code' . $mobile, json_encode($cacheData), (60 * 60));
        return true;
    }

    //获取缓存手机验证码
    public function getCode($mobile)
    {

        $cacheData = Cache::get('code' . $mobile);
        if (empty($cacheData)) {
            return false;
        }
        return json_decode($cacheData, true);
    }

    public function getMeritList($page, $limit, $type)
    {
        $w[] = ['openid', '<>', ''];
        if ($type == 1) {
            $order = 'merit_num desc';
        } elseif ($type == 2) {
            $order = 'merit_amount desc';
        } else {
            $order = '';
        }
        $list = Member::where($w)->order($order)->page($page, $limit)->field('member_id,avatar,nick,merit_amount,merit_num')->select();
        return $list;
    }
}